package open_api

import (
	"asoul-fan/museum-api/internal/open_api/api"
	"asoul-fan/museum-api/internal/open_api/service_context"
	"asoul-fan/museum-api/internal/pkg/app"
	"asoul-fan/museum-api/internal/pkg/config"
	"asoul-fan/museum-api/internal/pkg/database"
	"asoul-fan/museum-api/internal/pkg/http"
	"asoul-fan/museum-api/internal/pkg/log"
)

func InitApp(configFilename string) (*app.Application, error) {
	viper, err := config.New(configFilename)
	if err != nil {
		return nil, err
	}

	loggerOptions, err := log.NewOptions(viper)
	if err != nil {
		return nil, err
	}

	logger, err := log.NewLogger(loggerOptions)
	if err != nil {
		return nil, err
	}

	appOptions, err := NewOptions(viper, logger)
	if err != nil {
		return nil, err
	}
	httpOptions, err := http.NewOptions(viper, logger)
	if err != nil {
		return nil, err
	}
	databaseOptions, err := database.NewOptions(viper, logger)
	if err != nil {
		return nil, err
	}

	db, err := database.NewDatabase(databaseOptions)
	if err != nil {
		return nil, err
	}

	svc := service_context.NewServiceContext(viper, db)

	rr := api.NewRouterRegister(svc, logger)

	router := http.NewRouter(httpOptions, logger, rr.RegisterHandlers)

	server, err := http.NewServer(httpOptions, logger, router)
	if err != nil {
		return nil, err
	}

	application, err := NewApp(appOptions, logger, server)
	if err != nil {
		return nil, err
	}
	return application, nil
}
